package cn.easyutil.veteran.web.provider;

import cn.easyutil.veteran.core.entity.CommonPage;
import cn.easyutil.veteran.core.entity.ResponseEntity;
import cn.easyutil.veteran.core.error.CommonException;
import cn.easyutil.veteran.core.error.ErrorEnum;
import cn.easyutil.veteran.web.advice.BeforeResponseAdvice;
import cn.easyutil.veteran.web.session.SessionOperation;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;

import java.lang.reflect.Method;
import java.util.*;

public class DefaultBeforeResponseAdvice implements BeforeResponseAdvice {

    protected static final CommonPage EMPTY_PAGE = new CommonPage();
    protected static final Map<String,Object> EMPTY_OBJ = new HashMap<>();
    protected static final List<?> EMPTY_ARRAY = Collections.emptyList();

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object toPackage(Object outObj, Method method) {
        if(outObj instanceof ResponseEntity){
            return outObj;
        }
        Class<?> MethodReturnType = method.getReturnType();
        ResponseEntity<Object> rb = ResponseEntity.success();
        rb.setPayload(outObj);
        if (rb.getPayload() == null) {
            //返回值为空，要判断具体情况
            rb.setPayload(EMPTY_OBJ);
            if (IPage.class.isAssignableFrom(MethodReturnType) || Collection.class.isAssignableFrom(MethodReturnType)) {
                rb.setPayload(EMPTY_ARRAY);
                rb.setPage(EMPTY_PAGE);
            }
            return rb;
        } else if (IPage.class.isAssignableFrom(MethodReturnType)){
            //单独处理分页数据
            Page<?> data = (Page<?>) outObj;
            rb.setPayload(data.getRecords());
            rb.setPage(CommonPage.resolveMp(data));
        }
        return rb;
    }

    @Override
    public Object toSecret(Object outObj, Method method) {
        if(!(outObj instanceof ResponseEntity)){
            return outObj;
        }
        ResponseEntity body = (ResponseEntity) outObj;
        if(!body.isSuccess()){
            return body;
        }
        ResponseEntity secretBody = new ResponseEntity();
        BeanUtils.copyProperties(body,secretBody);
        Object payload = secretBody.getPayload();
        String secret = SessionOperation.getUser().getSecret();
        try {
            AES aes = SecureUtil.aes(secret.getBytes());
            String secretPayload = aes.encryptBase64(JSONUtil.toJsonStr(payload));
            secretBody.setPayload(secretPayload);
            return secretBody;
        } catch (Exception e) {
            return ResponseEntity.error(ErrorEnum.aes_encrypt_error);
        }
    }

    @Override
    public Object beforeBodyWrite(Object body, Method method) {
        return body;
    }
}
